package prvydevw.servlet;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import org.basex.core.BaseXException;
import org.basex.core.Context;
import org.basex.core.cmd.Close;
import org.basex.core.cmd.CreateDB;
import org.basex.core.cmd.Open;
import prvydevw.manager.BasexPaymentManager;
import prvydevw.manager.BasexSubjectManager;
import prvydevw.manager.PaymentManager;
import prvydevw.manager.SubjectManager;

@WebListener
public class StartListener implements ServletContextListener
{
    final static Logger log = Logger.getLogger(StartListener.class.getName());
    
    private Context context;

    @Override
    public void contextInitialized(ServletContextEvent ev)
    {
        log.info("Application initialised");
        
        ServletContext servletContext = ev.getServletContext();
        
        servletContext.setAttribute("subjectManager", subjectManager());
        servletContext.setAttribute("paymentManager", paymentManager());
        
        log.info("Managers created");
    }

    @Override
    public void contextDestroyed(ServletContextEvent ev)
    {
        try {
            new Close().execute(context());
        } catch (BaseXException ex) {
            log.log(Level.SEVERE, "Error when closing database", ex);
        }
        
        log.info("Application shutting down");
    }
    
    public Context context()
    {
        if (context == null) {
            context = new Context();
            
            if (!openDb()) {
                try {
                    createDb();
                } catch (BaseXException e) {
                    Logger.getLogger(StartListener.class.getName()).log(Level.SEVERE, "Error when creating db", e);
                }
            }
        }
        
        return context;
    }

    public SubjectManager subjectManager()
    {
        return new BasexSubjectManager(context());
    }

    public PaymentManager paymentManager()
    {
        return new BasexPaymentManager(context());
    }
    
    private boolean openDb()
    {
        try {
            new Open("DB").execute(context);
        } catch (BaseXException ex) {
            return false;
        }
        
        return true;
    }
    
    private void createDb() throws BaseXException
    {
        InputStream stream = new ByteArrayInputStream("<prvydevw><subjects /><payments /></prvydevw>".getBytes());

        CreateDB db = new CreateDB("DB");
        db.setInput(stream);
        db.execute(context);
    }
}